package com.itlong.cloud.abstracts;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <desc>
 *      所有服务Controller父类。
 * </desc>
 *
 * @createDate 2017/9/22
 */
public class BaseController {

    // key后面:为配置默认值，防止除App外其它聚合层因没配置这两个值而启动报错，此时默认值为空字符串
    @Value("${" + PlatformConstants.APP_REQUEST_PARAMS_ENCRYPT_KEY + ":}")
    public String APP_REQUEST_PARAMS_ENCRYPT_KEY;

    @Value("${" + PlatformConstants.APP_USER_TOKEN_KEY + ":}")
    public String APP_USER_TOKEN_KEY;

    /**
     * <desc>
     *      getway层公共异常处理.
     * <desc/>
     *
     * @param ex
     * @return xx
     * @author Wenchao.L
     * @createDate
     */
    @ExceptionHandler(value = DataAccessException.class)
    @ResponseBody
    public Object exceptionHandler(
            Exception ex,
            HttpServletRequest request) throws Exception {
        if (ex.getClass() == DataAccessException.class) {
            //入参密文
            String encryptScript = request.getParameter("encryptScript");
            //入参密文
            String cipherText = request.getParameter("ciphertext");

            MessageVO mv = new MessageVO();
            mv.setData(null);
            String[] message = ex.getMessage().split("】");
            if (message.length >= 2) {
                mv.setMsg(message[1]);
            }
            mv.setMsgCode(BaseErrorCodeEnum.getType(1));

            if (StringUtils.isNotBlank(encryptScript)) {
                return getEncryptResult(mv);
            } else if (StringUtils.isNotBlank(cipherText)) {
                return getEncryptResultApp(mv);
            } else {
                return mv;
            }
        }
        return null;
    }

    /**
     * <desc>
     *      返回APP加密内容
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/10/18
     */
    private Map<String, Object> getEncryptResultApp(Object result) throws Exception {
        JSONObject json = new JSONObject();
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String createTime = df.format(date);
        Map<String, Object> jsonToMap = new HashMap<>();
        jsonToMap.put("data", JsonUtil.toJSON(result));
        String sign = Md5EncryptUtil.cloudDeviceMd5(jsonToMap, createTime, APP_REQUEST_PARAMS_ENCRYPT_KEY);
        json.put("allData", JsonUtil.toJSON(result));
        json.put("createTime", createTime);
        json.put("sign", sign);
        String encryptResult = Base64.encode(DesEncryptUtil.Encrypt(URLEncoder.encode(new String(json.toJSONString().getBytes()), "utf-8").getBytes(), APP_USER_TOKEN_KEY));
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("ciphertext", encryptResult);
        return resultMap;
    }


    /**
     * <desc>
     *      返回加密内容
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/10/18
     */
    private Map<String, Object> getEncryptResult(Object result) throws Exception {
        String encryptResult = DesEncryptUtil.aesEncryptSDK(JsonUtil.toJSON(result), "5278MMN5412365UH");
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("encryptScript", encryptResult);
        return resultMap;
    }
}
